/**
 * 
 */
package cn.ad.server.web.servlet.v2.parser;

import cn.ad.server.common.utils.IPUtils;
import cn.ad.server.web.spring.model.AdRequest;
import cn.ad.server.web.spring.model.IAdserverRequest;
import cn.ad.server.web.spring.model.IAdserverResponse;

import javax.servlet.ServletInputStream;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * HttpServlet Json数据解析抽象类
 * @author Wu Chengjun
 *
 */
public abstract class AbstractHttpServletJsonParser extends HttpServletParserAdapter{
	
	private JsonStreamSerializer jsonStreamSerializer;
	
	private static final String CONTENT_TYPE_JSON = "application/json;charset=utf-8";
	
	public AbstractHttpServletJsonParser() {
		jsonStreamSerializer = new JacksonStreamSerializer();
	}
	
	public AbstractHttpServletJsonParser(JsonStreamSerializer jsonStreamSerializer) {
		super();
		this.jsonStreamSerializer = jsonStreamSerializer;
	}

	/* (non-Javadoc)
	 * @see cn.ad.server.web.servlet.parser.HttpServletParser#parse(javax.servlet.http.HttpServletRequest)
	 */
	@Override
	public IAdserverRequest parse(HttpServletRequest request) throws AdRequestParseException {
		AdRequest adRequest = null;
	    try (ServletInputStream inputStream = request.getInputStream()){
	    	adRequest = (AdRequest) jsonStreamSerializer.deserialize(inputStream, getAdRequestClassType());
		} catch (JSoneSerializeException e) {
			throw new AdRequestParseException("解析出现异常:源 IP[" + IPUtils.parseIp(request) + "], url[" + request.getRequestURL() + "]; 异常消息:" + e.getMessage(), e);
		} catch (IOException e) {
			throw new AdRequestParseException(e.getMessage(), e);
		}
        return adRequest;
	}
	
	/* (non-Javadoc)
	 * @see cn.ad.server.web.servlet.parser.HttpServletParser#writeResponse(cn.falconnect.adserver.adapter.AdResponse, javax.servlet.http.HttpServletResponse)
	 */
	@Override
	public void writeResponse(IAdserverResponse adResponse, HttpServletResponse response) throws AdRequestParseException {
		try (ServletOutputStream outputStream = response.getOutputStream()){
			response.setContentType(CONTENT_TYPE_JSON);
			jsonStreamSerializer.serialize(outputStream, adResponse);
		} catch (JSoneSerializeException e) {
			throw new AdRequestParseException(e.getCause());
		} catch (IOException e) {
			throw new AdRequestParseException(e.getCause());
		}
	}

	/**
	 * 返回AdRequest子类类型
	 * @return
	 */
	public abstract Class<?> getAdRequestClassType();
}
